import 'package:flutter/foundation.dart';
import 'package:flutter_layout/base/index.dart';
import 'package:logger/logger.dart';

class PrintUtils {
//调试模式断言
// 在Flutter应用调试过程中，Dart assert语句被启用，
//并且 Flutter 框架使用它来执行许多运行时检查来验证是否违反一些不可变的规则。
//当一个某个规则被违反时，就会在控制台打印错误日志，并带上一些上下文信息来帮助追踪问题的根源。
// 要关闭调试模式并使用发布模式，请使用flutter run --release运行我们的应用程序。
// 这也关闭了Observatory调试器。一个中间模式可以关闭除Observatory之外所有调试辅助工具的，
//称为“profile mode”，用--profile替代--release即可。

  static printByApp(string, {Level? level = Level.warning}) {
    if (kDebugMode) {
      // debugger(when: true);//运行时断点
      // print(string);
      // debugPrint(string);
      // log("string=$string",level: 0);
      // Logger().i(string);
      // Logger().e(string);
      // Logger().d(string);
      // Logger().v(string);
      // Logger().w(string);
      // Logger().wtf(string);
      // Logger().log(level!, string);
      if (level == Level.debug) {
        logger.d(string);
      } else if (level == Level.info) {
        logger.i(string);
      } else if (level == Level.warning) {
        logger.w(string);
      } else if (level == Level.wtf) {
        logger.wtf(string);
      } else if (level == Level.error) {
        logger.e(string);
      } else if (level == Level.verbose) {
        logger.v(string);
      } else {
        logger.w(string);
      }
      // 要转储Widgets树的状态，请调用debugDumpApp() (opens new window)。
      // 只要应用程序已经构建了至少一次（即在调用build()之后的任何时间），
      //我们可以在应用程序未处于构建阶段（即，不在build()方法内调用 ）的任何时间调用此方法（在调用runApp()之后）。
      // debugDumpApp();

      // 渲染树
      // 如果我们尝试调试布局问题，那么Widget树可能不够详细。在这种情况下，
      //我们可以通过调用debugDumpRenderTree()转储渲染树。 正如debugDumpApp()，
      //除布局或绘制阶段外，我们可以随时调用此函数。作为一般规则，从frame 回调 (opens new window)或事件处理器中调用它是最佳解决方案。
      // 要调用debugDumpRenderTree()，我们需要添加import'package:flutter/rendering.dart';到我们的源文件。
      // debugDumpRenderTree();

      //Layer 树
      // debugDumpLayerTree();
      //聚焦树
      // debugDumpFocusTree();

      //语义树
      //我们还可以调用debugDumpSemanticsTree() (opens new window)获取语义树（呈现给系统可访问性API的树）的转储。 要使用此功能，必须首先启用辅助功能，例如启用系统辅///助工具或SemanticsDebugger （下面讨论）。
      // debugDumpSemanticsTree(childOrder);

      //调度
      // 要找出相对于帧的开始/结束事件发生的位置，可以切换debugPrintBeginFrameBanner (opens new window)和debugPrintEndFrameBanner (opens new window)布尔值以将帧的开始和结束打印到控制台。
      // debugPrintScheduleFrameStacks

      //可视化调试
      // 我们也可以通过设置debugPaintSizeEnabled为true以可视方式调试布局问题。 这是来自rendering库的布尔值。它可以在任何时候启用，并在为true时影响绘制。 设置它的最简单方法是在void main()的顶部设置。

      // 当它被启用时，所有的盒子都会得到一个明亮的深青色边框，padding（来自widget如Padding）显示为浅蓝色，子widget周围有一个深蓝色框， 对齐方式（来自widget如Center和Align）显示为黄色箭头. 空白（如没有任何子节点的Container）以灰色显示。

      // debugPaintBaselinesEnabled (opens new window)做了类似的事情，但对于具有基线的对象，文字基线以绿色显示，表意(ideographic)基线以橙色显示。

      // debugPaintPointersEnabled (opens new window)标志打开一个特殊模式，任何正在点击的对象都会以深青色突出显示。 这可以帮助我们确定某个对象是否以某种不正确的方式进行hit测试（Flutter检测点击的位置是否有能响应用户操作的widget）,例如，如果它实际上超出了其父项的范围，首先不会考虑通过hit测试。

      // 如果我们尝试调试合成图层，例如以确定是否以及在何处添加RepaintBoundary widget，则可以使用debugPaintLayerBordersEnabled (opens new window)标志， 该标志用橙色或轮廓线标出每个层的边界，或者使用debugRepaintRainbowEnabled (opens new window)标志， 只要他们重绘时，这会使该层被一组旋转色所覆盖。

      // 所有这些标志只能在调试模式下工作。通常，Flutter框架中以“debug...” 开头的任何内容都只能在调试模式下工作。

      // #调试动画
      // 调试动画最简单的方法是减慢它们的速度。为此，请将timeDilation (opens new window)变量（在scheduler库中）设置为大于1.0的数字，例如50.0。 最好在应用程序启动时只设置一次。如果我们在运行中更改它，尤其是在动画运行时将其值改小，则在观察时可能会出现倒退，这可能会导致断言命中，并且这通常会干扰我们的开发工作。

      // #调试性能问题
      // 要了解我们的应用程序导致重新布局或重新绘制的原因，我们可以分别设置debugPrintMarkNeedsLayoutStacks (opens new window)和 debugPrintMarkNeedsPaintStacks (opens new window)标志。 每当渲染盒被要求重新布局和重新绘制时，这些都会将堆栈跟踪记录到控制台。如果这种方法对我们有用，我们可以使用services库中的debugPrintStack()方法按需打印堆栈痕迹。

      // #统计应用启动时间
      // 要收集有关Flutter应用程序启动所需时间的详细信息，可以在运行flutter run时使用trace-startup和profile选项。

      // $ flutter run --trace-startup --profile
      // 跟踪输出保存为start_up_info.json，在Flutter工程目录在build目录下。输出列出了从应用程序启动到这些跟踪事件（以微秒捕获）所用的时间：

      // 进入Flutter引擎时.
      // 展示应用第一帧时.
      // 初始化Flutter框架时.
      // 完成Flutter框架初始化时.
      // 如 :

      // {
      //   "engineEnterTimestampMicros": 96025565262,
      //   "timeToFirstFrameMicros": 2171978,
      //   "timeToFrameworkInitMicros": 514585,
      //   "timeAfterFrameworkInitMicros": 1657393
      // }
      // #跟踪Dart代码性能
      // 要执行自定义性能跟踪和测量Dart任意代码段的wall/CPU时间（类似于在Android上使用systrace (opens new window)）。 使用dart:developer的Timeline (opens new window)工具来包含你想测试的代码块，例如：

      // Timeline.startSync('interesting function');
      // iWonderHowLongThisTakes();
      // Timeline.finishSync();
      // 然后打开你应用程序的Observatory timeline页面，在“Recorded Streams”中选择‘Dart’复选框，并执行你想测量的功能。

      // 刷新页面将在Chrome的跟踪工具 (opens new window)中显示应用按时间顺序排列的timeline记录。

      // 请确保运行flutter run时带有--profile标志，以确保运行时性能特征与我们的最终产品差异最小。

      // 运行flutter run --trace-startup --profile
      // 生成start_up_info.json
      // 下面是生成的文件内容
      // {
      //   "engineEnterTimestampMicros": 293012763376,
      //   "timeToFrameworkInitMicros": 165454,
      //   "timeToFirstFrameRasterizedMicros": 381154,
      //   "timeToFirstFrameMicros": 179634,
      //   "timeAfterFrameworkInitMicros": 14180
      // }

    }
  }
}
